/***********************************************************************************
 * 文件名： switch_ctrl.h
 * 版本： 2
 * 说明：
 *      switch ctrl （开关量控制器）
 *      提供控制开关量的API: 开、关、闪烁（间断开关）、输出指定PWM值、渐变（PWM值大小变化）。
 *      类似于 sled_ctrl_static 那样操作任意开关量，面向对象设计，可实例化多个对象，单个对象可
 *  控制多个通道，可以用于替代 sled_ctrl_static 和 cled_ctrl_static .
 *      依耐 polsys，且开启用户参数。
 * 修改记录：
 * 	2023/12/09: 初版。 刘言。
 *  2024/07/05: 之间参数单位改为ms。刘言。
***********************************************************************************/
#ifndef _SWITCH_CTRL_H_
#define _SWITCH_CTRL_H_

#include "..\..\polsys.h"

// 自定义类型

typedef enum _swc_action_t // 动作（状态）
{
    SWC_ACT_NULL, // 输出已经OFF，没有任何动作，空闲
    SWC_ACT_WAIT, // OFF后等待输出确实关闭，因为PWM控制器一个周期后才会更新，这里只等待10ms
    SWC_ACT_ON,   // 输出开启
    SWC_ACT_OFF,  // 输出关闭
    SWC_ACT_FLASH,  // 闪烁（周期性开关），可设置闪烁速度
    SWC_ACT_GRA_ON,   // 渐亮（PWM值缓慢到最高）
    SWC_ACT_GRA_OFF,  // 渐灭 (PWM值缓慢到最低)
    SWC_ACT_BREATH, // 呼吸（PWM值缓慢高低）
    SWC_ACT_GRA_COLOR, // 彩色渐变（3个通道轮换渐变）
    _SWC_ACT_END
} swc_action_t;

typedef enum _swc_ev_t
{
    SWC_EV_ACT_NULL,    // 空闲事件，动作变为 SWC_ACT_NULL ，通常是动作执行完毕时触发。
    SWC_EV_ACT_STARTED, // 开始动作事件，动作变为非 SWC_ACT_NULL ，通常动作被设置时触发，可以处理一些动作前的额外准备工作。
    _SWC_EV_END
}swc_ev_t;

// 设置输出值的函数的类型，需要用户实现。ch代表开关量编号（通道编号，目前0~2），value值的范围为0~255。
typedef void (*swc_set_value_fun_t)(u8 ch, u8 value);

// 事件通知（回掉）函数的类型，可选实现
typedef void (*swc_cb_t)(swc_ev_t e);

// swc “类”（对象的数据）
typedef struct _swc_t
{
    polsys_task_t SwcTimer;    // 软定时器

    u16 Time;               // 计时
    u16 Count;              // 计数
    swc_action_t Action;    // 动作
    u8 Value[3];            // 各通道的值，暂时固定支持3个通道
    u16 ActionTime;         // 动作时间控制参数
    u16 ActionCount;        // 动作次数/速度控制参数

    swc_set_value_fun_t SetValue;   // 设置值的函数
    swc_cb_t Callback;      // 事件回调函数
}swc_t;

// APIs

/**
 * 初始化一个 SWC 对象。暂时固定支持3个通道。
 * @param obj 要初始化的对象
 * @param fun 设置输出值的函数，需要用户实现。值的范围为0~255。
*/
void Swc_Init(swc_t *obj, swc_set_value_fun_t fun);

/**
 * 设置事件回调函数，暂时只支持一个回调函数，重复设置会被覆盖
*/
void Swc_SetCallback(swc_t *obj, swc_cb_t callbackfun);

/**
 * 设置动作。
 * @param obj 要设置的对象。
 * @param action 动作。
 * @param time 动作的时间参数，单位ms，-1代表无穷大。
 * SWC_ACT_ON：代表开启的时间。
 * SWC_ACT_OFF：无意义。
 * SWC_ACT_FLASH：代表闪烁的二分之一周期。
 * SWC_ACT_GRA_ON：代表渐亮后维持亮的时间，时间到后自动渐灭。
 * SWC_ACT_GRA_OFF：无意义。
 * SWC_ACT_BREATH: 代表呼吸动作的时间。
 * SWC_ACT_GRA_COLOR：代表彩色渐变动作的时间。
 * @param count 动作的次数/速度参数。
 * SWC_ACT_ON：无意义。
 * SWC_ACT_OFF：无意义。
 * SWC_ACT_FLASH：代表闪烁的次数。
 * SWC_ACT_GRA_ON：决定渐亮的速度，值越大亮的越快（渐亮过程越短），建议设置为5。
 * SWC_ACT_GRA_OFF：决定渐灭的速度，值越大灭的越快（渐灭过程越短），建议设置为5。
 * SWC_ACT_BREATH: 决定呼吸的速度，建议设置为5。
 * SWC_ACT_GRA_COLOR：决定彩色渐变的速度，建议设置为1。
*/
void Swc_SetAction(swc_t *obj, swc_action_t action, int time, int count);

/**
 * 设置“开”所代表的输出值，即全开时的PWM值，默认255，注意这会影响所有需要开启的动作。
 * 如果控制的是RGBLED，可在这里分别设置每个颜色通道来设置显示的颜色。
 * @param obj 要设置的对象
 * @param num 需要设置的输出通道(0~2)，对应 swc_set_value_fun_t 中的参数。
*/
void Swc_SetValue(swc_t *obj, u8 num, u8 value);

/**
 * 设置颜色。
 * 如果控制的是RGBLED，这个API很有用。实际上是同时设置了3个通道的值。
 * @param color RGB颜色，0X00RRGGBB 。
*/
void Swc_SetColor(swc_t *obj, u32 color);

// 获取当前在执行的动作
swc_action_t Swc_GetAction(swc_t *obj);




#endif
